package com.stars.easyms.datasource.mybatis;

import lombok.Setter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.util.Assert.notNull;

/**
 * <p>className: EasyMsMapperScannerConfigurer</p>
 * <p>description: EasyMs自定义Mapper扫描配置类：因为mybatis的dao层无法被PointcutAdvisor拦截，因此自定义实现PointcutAdvisor拦截</p>
 *
 * @author guoguifang
 * @version 1.2.1
 * @date 2019-05-08 10:22
 */
public final class EasyMsMapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean {

    @Setter
    private String basePackage;

    @Setter
    private String sqlSessionTemplateBeanName;

    @Setter
    private String sqlSessionFactoryBeanName;

    private final List<Class<? extends Annotation>> annotationClassList;

    private final List<Class<?>> markerInterfaceList;

    private ConfigurableApplicationContext applicationContext;

    private EasyMsClassPathMapperScanner scanner;

    @Override
    public synchronized void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        if (scanner == null) {
            scanner = new EasyMsClassPathMapperScanner(applicationContext, registry);
            scanner.setAddToConfig(true);
            scanner.setAnnotationClassList(annotationClassList);
            scanner.setMarkerInterfaceList(markerInterfaceList);
            if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
                scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
            } else {
                scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
            }
            scanner.registerFilters();
            scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
        }
    }

    public void addAnnotationClass(Class<? extends Annotation> annotationClass) {
        annotationClassList.add(annotationClass);
    }

    public void addMarkerInterface(Class<?> markerInterface) {
        markerInterfaceList.add(markerInterface);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) {
        // intentionally blank
    }

    @Override
    public void afterPropertiesSet() {
        notNull(this.basePackage, "Property 'basePackage' is required");
    }

    public EasyMsMapperScannerConfigurer(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.annotationClassList = new ArrayList<>();
        this.markerInterfaceList = new ArrayList<>();
    }

}